<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>websocket</title>
    <script type="text/javascript" src="http://cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script>
    <script type="text/javascript" src="http://cdn.bootcss.com/sockjs-client/1.1.1/sockjs.js"></script>

    <script type="text/javascript">
        var websocket = null;
        var retryInterval = null;
        var heartBeatInterval = null;

        function connWs() {
            if ('WebSocket' in window) {
                websocket = new WebSocket("ws://localhost/websocket/server");
            } else if ('MozWebSocket' in window) {
                websocket = new MozWebSocket("ws://localhost/websocket/server");
            } else {
                websocket = new SockJS("http://localhost/sockjs/server");
            }
            websocket.onopen = onOpen;
            websocket.onmessage = onMessage;
            websocket.onerror = onError;
            websocket.onclose = onClose;
        }

        // 监听窗口事件，当窗口关闭时，主动断开websocket连接，防止连接没断开就关闭窗口，server端报错
        window.onbeforeunload = function () {
            onClose();
        }

        function onOpen(event) {
            console.log("连接成功!");
            heartCheck.reset().start();
            retryInterval && clearInterval(retryInterval);
            heartBeatInterval = self.setInterval("heartBeat()", 3000);
        }

        /**
         * 心跳
         * */
        function heartBeat() {
            websocket.send("heartBeat");
        }

        function onMessage(messageEvent) {
            console.log(messageEvent.data);
            heartCheck.reset().start();
        }

        function onError(event) {
        }

        function onClose(closeEvent) {
            console.log(closeEvent.reason);
            websocketClose();
        }

        /**
         * 发送消息
         */
        function doSendUser() {
            if (websocket.readyState === websocket.OPEN) {
                var toUser = document.getElementById("toUser").value;
                var msg = document.getElementById("inputMsg").value;
                websocket.send(toUser, msg);
                // users.get(id).sendMessage(message);
                // IM =="{code;"", msg:\"\"}"
                console.log("发送成功!");
            } else {
                console.log("连接失败!");
            }
        }

        window.close = function () {
            websocket.onclose();
        };

        function websocketClose() {
            websocket.close();
            console.log("连接关闭");
            clearInterval(heartBeatInterval);
            // 尝试重连
            retryInterval = self.setInterval("connWs()", 3000);
        }

        // 心跳检测, 每隔一段时间检测连接状态，如果处于连接中，就向server端主动发送消息，来重置server端与客户端的最大连接时间，如果已经断开了，发起重连。
        var heartCheck = {
            timeout: 3000,        // 9分钟发一次心跳，比server端设置的连接时间稍微小一点，在接近断开的情况下以通信的方式去重置连接时间。
            serverTimeoutObj: null,
            reset: function () {
                clearTimeout(this.timeoutObj);
                clearTimeout(this.serverTimeoutObj);
                return this;
            },
            start: function () {
                var self = this;
                this.serverTimeoutObj = setInterval(function () {
                    if (websocket.readyState == 1) {
                        console.log("连接状态，发送消息保持连接");
                        websocket.send("ping");
                        heartCheck.reset().start();    // 如果获取到消息，说明连接是正常的，重置心跳检测
                    } else {
                        console.log("断开状态，尝试重连");
                        newWebSocket();
                    }
                }, this.timeout)
            }
        }
        connWs();
    </script>
</head>
<body>
发送对象：<input id="toUser" name="toUser"/>
发送消息：<input id="inputMsg" name="inputMsg"/>
<button id="sendBtn">发送</button>
<button οnclick="websocketClose();">关闭连接</button>
</body>
<script>
    $("#sendBtn").click(doSendUser);
</script>
</html>